﻿using System;
using System.Web;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Steve.TestHelper;
using Steve.UI.Extensions;
using Steve.UI.Modules;
using System.Collections.Generic;

namespace Steve.UI.Tests
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class SteveSiteModule_Tests : ComposablePartTests
    {
        public override List<Type> GetTypesForCatalog()
        {
            var list = base.GetTypesForCatalog();

            list.Add(typeof(DefaultRewriter));

            return list;
        }

        [TestMethod]
        public void ArgumentNullException_Tests()
        {
            var module = new SteveSiteModule();

            //ExceptionAssert.ThrowsArgumentNullException(() => module.Rewrite(null, null), "ctx");
            //ExceptionAssert.ThrowsArgumentNullException(() => module.IsSecureConnection(null), "ctx");
        }

        private void TestRewrite(Uri expected, Uri original)
        {
            var ctx = HttpContextExport;
          
            ctx.Request.Mock(mock => mock.Setup(req => req.Url).Returns(original));
            ctx.Request.Mock(mock => mock.Setup(req => req.IsSecureConnection).Returns(original.Scheme == "https"));

            ctx.Response.Mock(mock => mock.Setup(resp => resp.End()).Verifiable());
            ctx.Response.Mock(mock => mock.SetupSet(resp => resp.StatusCode = 301).Verifiable());
            ctx.Response.Mock(mock => mock.SetupSet(resp => resp.Status = "301 Moved Permanently").Verifiable());
            ctx.Response.Mock(mock => mock.SetupSet(resp => resp.RedirectLocation = expected.ToString()).Verifiable());

            var module = new SteveSiteModule();

            ScopedContainer.Compose(module);

            module.HandleBeginRequest(ctx);

            ctx.Response.Mock(mock => mock.Verify());
        }

        [TestMethod]
        public void Test_Rewrite_Case_MisMatch()
        {
            var original = new Uri("http://testdomain.com/testURL/");
            var expected = new Uri("http://testdomain.com/testurl/");

            StubSiteExplorerRepository.AddSite("testdomain", expected.Authority);
            var expectedUrlObject = StubSiteExplorerRepository.AddUrl("testdomain", "Test URL", expected.AbsolutePath);

            TestRewrite(expected, original);

            var matchUrlObject = HttpContextExport.GetUrlMatch();
            Assert.IsNotNull(matchUrlObject);
            Assert.AreSame(expectedUrlObject, matchUrlObject);
        }

        [TestMethod]
        public void Test_Rewrite_SSL_MisMatch()
        {
            var original = new Uri("http://testdomain.com/testurl/");
            var expected = new Uri("https://testdomain.com/testurl/");

            StubSiteExplorerRepository.AddSite("testdomain", expected.Authority);
            var expectedUrlObject = StubSiteExplorerRepository.AddUrl("testdomain", "Test URL", expected.AbsolutePath, null, null, true);

            TestRewrite(expected, original);

            var matchUrlObject = HttpContextExport.GetUrlMatch();
            Assert.IsNotNull(matchUrlObject);
            Assert.AreSame(expectedUrlObject, matchUrlObject);
        }

        [TestMethod]
        public void Test_Basic_Rewrite_Same_Site()
        {
            var original = new Uri("http://testdomain.com/testurl/");
            var expected = new Uri("http://testdomain.com/testurl2/");

            StubSiteExplorerRepository.AddSite("testdomain", expected.Authority);
            var url = StubSiteExplorerRepository.AddUrl("testdomain", "Test URL", expected.AbsolutePath);
            var expectedUrlObject = StubSiteExplorerRepository.AddRewrite(url.Id, "testdomain", original.AbsolutePath);

            TestRewrite(expected, original);

            var matchUrlObject = HttpContextExport.GetUrlMatch();
            Assert.IsNotNull(matchUrlObject);
            Assert.AreSame(expectedUrlObject, matchUrlObject);
        }

        [TestMethod]
        public void Test_Rewrite_Site_Alt_Authority()
        {
            var original = new Uri("http://testdomain.com/");
            var expected = new Uri("http://www.testdomain.com/");

            StubSiteExplorerRepository.AddSite("testdomain", expected.Authority);
            StubSiteExplorerRepository.AddSiteAlt("testdomain", original.Authority);
            var expectedUrlObject = StubSiteExplorerRepository.AddUrl("testdomain", "Test URL", expected.AbsolutePath);
            
            TestRewrite(expected, original);

            var matchUrlObject = HttpContextExport.GetUrlMatch();
            Assert.IsNotNull(matchUrlObject);
            Assert.AreSame(expectedUrlObject, matchUrlObject);
        }

        [TestMethod]
        public void Test_QueryString_Match()
        {
            var test = new Uri("http://www.somesite.com/directory/page.aspx?param=value");

            StubSiteExplorerRepository.AddSite("test", test.Authority);
            var expectedUrlObject = StubSiteExplorerRepository.AddUrl("test", "Test URL", test.PathAndQuery, null, null, false, false);

            var ctx = HttpContextExport;
            ctx.Request.Mock(mock => mock.Setup(req => req.Url).Returns(test));
            ctx.Request.Mock(mock => mock.Setup(req => req.IsSecureConnection).Returns(test.Scheme == "https"));

            var module = new SteveSiteModule();
            ScopedContainer.Compose(module);
            module.HandleBeginRequest(ctx);

            ctx.Response.Mock(mock => mock.Verify());

            var matchUrlObject = ctx.GetUrlMatch();
            Assert.IsNotNull(matchUrlObject);
            Assert.AreSame(expectedUrlObject, matchUrlObject);
        }

        [TestMethod]
        public void Test_Rewrite_No_Match()
        {
            var dummy = new Uri("http://www.google.com/");
            var test = new Uri("http://www.testdomain.com/");

            StubSiteExplorerRepository.AddSite("dummy", dummy.Authority);
            StubSiteExplorerRepository.AddUrl("dummy", "Dummy URL", dummy.AbsolutePath);


            var ctx = HttpContextExport;
            ctx.Request.Mock(mock => mock.Setup(req => req.Url).Returns(test));
            ctx.Request.Mock(mock => mock.Setup(req => req.IsSecureConnection).Returns(test.Scheme == "https"));

            var module = new SteveSiteModule();
            ScopedContainer.Compose(module);
            module.HandleBeginRequest(ctx);

            ctx.Response.Mock(mock => mock.Verify());

            var matchUrlObject = ctx.GetUrlMatch();
            Assert.IsNull(matchUrlObject);
        }

        [TestMethod]
        public void Test_Rewrite_DateRange_Live()
        {
            Assert.Inconclusive();
        }

        [TestMethod]
        public void Test_Rewrite_DateRange_Dead()
        {
            Assert.Inconclusive();
        }

    }
}


